/* 
Copyright (c) 2008 Chumby Industries

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
import com.gskinner.events.GDispatcher;
import com.chumby.util.Delegate;

class com.chumby.widgets.photostrip.Photo extends MovieClip
{
	// passed in during attachMovie:
	private var imagePath:String;
	private var imageType:String;
	private var imageName:String;
	private var noteContents:String;
	private var isPlaying:Object = {playing:false};
	
	private var _maxWidth:Number;
	private var _maxHeight:Number;
	
	private var _loadState:Number;
	private var _photo:MovieClip;
	private var _keepLoaded:Boolean;
	private var _mcl:MovieClipLoader;
	private var status_txt:TextField;
	private var status_contents:TextField;
	private var _playButton:MovieClip;
	private var _audioFile:Sound;
	private var _errorCount:Number;
	
	private var Width:Number;
	private var Height:Number;
	
	private var UNLOAD_T:Number;
	private var LOAD_T1:Number;
	private var LOAD_T2:Number;
	
	private var _timerTest:Number;

	private static var MAX_LOADING:Number = 4;
	private static var NumLoading:Number = 0;
	
	public static var LOADING:Number = 1;
	public static var LOADED:Number = 2;
	public static var UNLOADED:Number = 3;
	public static var LOAD_ERR:Number = 4;
	
	public var addEventListener:Function;
	public var removeEventListener:Function;
	private var dispatchEvent:Function;
	
	//-----------------------------------------------------------------------------------------------
	public static function numLoading():Number {
		return NumLoading;
	}
	
	private function setHeight(h:Number) {
		Height = h;
	}

	private function setWidth(w:Number) {
		Width = w;
		UNLOAD_T = w * 3;
		LOAD_T1  = w * 2.5;
		LOAD_T2  = w * 1.5;
	}
	
	//-----------------------------------------------------------------------------------------------
	function Photo()
	{
		/* variables passed in during attachMovie:
			imagePath
			_maxWidth
			_maxHeight
		*/
		_loadState = UNLOADED;
		_keepLoaded = false;		
		_errorCount = 0;
		status_txt = this.createTextField("status", this.getNextHighestDepth() + 1, 5, 110, 310, 24);
		status_contents = this.createTextField("status_contents", this.getNextHighestDepth() + 2, 5, 110, 310, 180);
		_mcl = new MovieClipLoader();
		_mcl.addListener(this);
		GDispatcher.initialize(this);
		init();
	}

	//-----------------------------------------------------------------------------------------------
	private function init()
	{
		if(_maxWidth != undefined) {
			setWidth(_maxWidth);
		}
		else {
			setWidth(320);
		}
		if(_maxHeight != undefined) {
			setHeight(_maxHeight);
		}
		else {
			setHeight(240);
		}
	}
	
	//-----------------------------------------------------------------------------------------------
	public function keepLoaded()
	{
		_keepLoaded = true;
	}
	
	//-----------------------------------------------------------------------------------------------
	// this function is called from the parent movieclip as it moves.
	// the strategy here is to load photos when they're near the display, and unload them otherwise.
	// the "unload" range is larger for hysteresis to discourage thrashing.  We also try to
	// load the images when the images are "stopped", unless they're too close.
	public function checkLoad() 
	{
		var offset:Number = this._x + this._parent._x;// + Width/2;
		if (_loadState == LOADED && _keepLoaded == false)
		{
			if (offset < -UNLOAD_T || offset > UNLOAD_T)
			{
				//trace('unloading '+this+' (offset '+offset+')');
				_mcl.unloadClip(_photo);
				_loadState = UNLOADED;
				dispatchEvent({type:UNLOADED});
			}
		} 
		else if((_loadState == UNLOADED) && (NumLoading < MAX_LOADING) && (_errorCount < 3) )
		{
			if (imageType == "image")
			{
				if ((_parent._isStopped && offset > -LOAD_T1 && offset < LOAD_T1) || 
					(offset > -LOAD_T2 && offset < LOAD_T2)) 
				{
					//trace(this._name + " loading jpg.  ");
					_photo = createEmptyMovieClip('photo',this.getNextHighestDepth());
					this._timerTest = getTimer();
					_mcl.loadClip(imagePath, _photo);
					NumLoading++;
					_loadState = LOADING;
					dispatchEvent({type:LOADING});
					showLoadingMessage();
				}
			}
			else if (imageType == "audio")
			{
				if ((_parent._isStopped && offset > -LOAD_T1 && offset < LOAD_T1) || 
					(offset > -LOAD_T2 && offset < LOAD_T2)) 
				{
					showAudioFile(imageName);
				}
			}
			else if (imageType == "note")
			{
				//trace('showing note with ' + noteContents);
				showNote(imageName, noteContents);
			}
		}
	}

	//-----------------------------------------------------------------------------------------------
	private function showLoadingMessage()
	{
		status_txt.text = "Loading Image...";
		var my_fmt:TextFormat = new TextFormat();
		my_fmt.color = 0xffffff;
		my_fmt.align = "center"
		my_fmt.size = 15;
		my_fmt.font = "Arial";
		status_txt.setTextFormat(my_fmt);
	}

	private function showAudioFile(name:String)
	{
		if (!_playButton) {
			trace("showAudioFile");
			status_txt.text = "Audio: " + name;
			var my_fmt:TextFormat = new TextFormat();
			my_fmt.color = 0xffffff;
			my_fmt.align = "center"
			my_fmt.size = 15;
			my_fmt.font = "Arial";
			status_txt.setTextFormat(my_fmt);
			status_txt._y = 90;
			_playButton = this.attachMovie("DCPlayButton.png", "pb" + name, 
				this.getNextHighestDepth() + 2, { _x: 116, _y: 124 } );
		}
	}
	
	private function showNote(title:String, noteContents:String)
	{
		status_txt.text = title;
		status_contents.html = true;
		status_contents.wordWrap = true;
		status_contents.background = true;
		status_contents.backgroundColor = 0xffffff;
		status_contents.htmlText = simplifyHtml(noteContents);
		var my_fmt:TextFormat = new TextFormat();
		my_fmt.color = 0xffffff;
		my_fmt.align = "center"
		my_fmt.size = 14;
		my_fmt.font = "Arial";
		status_txt.setTextFormat(my_fmt);
		status_txt._y = 10;
		
		var my_cfmt:TextFormat = new TextFormat();
		my_cfmt.color = 0x555555;
		my_cfmt.align = "left"
		my_cfmt.size = 13;
		my_cfmt.font = "Arial";
		status_contents.setTextFormat(my_cfmt);
		status_contents._y = 30;
		

		// Delegate.create(this, playAudioFile);
	}
	public function simplifyHtml(orig:String) {
		//trace(orig);
		var simp:String;
		simp = searchAndReplace(orig, "<strong>", "<b>");
		simp = searchAndReplace(simp, "</strong>", "</b>");
		simp = searchAndReplace(simp, "<em>", "<i>");
		simp = searchAndReplace(simp, "</em>", "</i>");
		return(simp);
	}
	public function searchAndReplace(holder, searchfor, replacement) {
		var temparray:Array;
		temparray = holder.split(searchfor);
		holder = temparray.join(replacement);
		return (holder);
	}

	public function playAudioFile():Void
	{
		trace("playAudioFile");
		_audioFile = new Sound();
		var a = _audioFile;
		var p = _parent;
		var iP = isPlaying;
		// _audioFile.onLoad = function(success:Boolean) { if (success) { a.start(); iP.playing = true; }  else { p.setAutoAdvance(true); iP.playing = false; } };
		_audioFile.onSoundComplete = function() { p.setAutoAdvance(true); iP.playing = false; };
		_audioFile.loadSound(imagePath, true);
		_parent.setAutoAdvance(false);
		iP.playing = true;
		//_playButton.loadMovie("DCPauseButton.png");
	}
	
	public function stopAudioFile():Void
	{
		trace("stopAudioFile");
		var iP = isPlaying;
		iP.playing = false;
		//_audioFile = new Sound();
		//_playButton.loadMovie("DCPlayButton.png");
		_parent.setAutoAdvance(true);
		if(_audioFile){
			_audioFile.stop();
			_audioFile = null;
		}
	}
	
	public function toggleAssetPlaying():Void {
		var iP = isPlaying;
		if (iP.playing) {
			stopAudioFile();
		}else {
			playAudioFile();
		}
	}
	public function isPlayable():Boolean
	{
		return (imageType == 'audio');
	}
	
	private function hideLoadingMessage()
	{
		status_txt.text = "";
	}
	
	private function showErrorMessage ()
	{
		status_txt.text = "Error.";
		var my_fmt:TextFormat = new TextFormat();
		my_fmt.color = 0xffffff;
		my_fmt.align = "center"
		my_fmt.size = 15;
		my_fmt.font = "Arial";
		status_txt.setTextFormat(my_fmt);
	}
	
	//-----------------------------------------------------------------------------------------------
	// basic resizing/centering code after the image has been loaded
	private function onLoadInit(target:MovieClip) 
	{
		if(target._width == 0) 
		{
			onLoadError(target);
			return;
		}
		
		var n:Number = (getTimer() - this._timerTest);
		NumLoading--;
		_loadState = LOADED;
		dispatchEvent({type:LOADED, name:this._name});
		hideLoadingMessage();
		var scaleX:Number = Math.min(1, Width/_photo._width);
		var scaleY:Number = Math.min(1, Height/_photo._height);
		var scale:Number = Math.min(scaleX,scaleY);
		if(scale != 1) 
		{
			_photo._width  = scale * _photo._width;
			_photo._height = scale * _photo._height;
		}
		_photo._x = (Width-_photo._width)/2;
		_photo._y = (Height-_photo._height)/2;
	}
	
	//-----------------------------------------------------------------------------------------------
	// on chumby onLoadError doesn't get called directly, but we call it from onLoadInit if _width is 0
	private function onLoadError(target:MovieClip)
	{
		trace("* onLoadError Aborting Load *");
		_errorCount++;
		if (_errorCount > 2)
		{
			_loadState = LOADED;
			keepLoaded();
			hideLoadingMessage();
			showErrorMessage();
		}
		else
		{
			_loadState = UNLOADED;
			hideLoadingMessage();
		}
		NumLoading--;
		dispatchEvent({type:LOAD_ERR});
	}
}
